import datetime
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from jili.core import sendemail as mail
from jili.data import db as dba
from jili.core.convert import converttype,originalname,arg2argkv
from jili.report import status
from bs4 import BeautifulSoup
from jili.calc import operator
from jili.calc import tag

def expdist(x,yita,delta=0):
    return yita*np.exp(-yita*(x-delta))
def expdist1(x,yita=0.5):
    return expdist(x,yita,1)
def expdist2(x,yita=0.5):
    return expdist(x,yita,2) 
def varloss(x):
    return 1-1/(1+x)
def varprofit(x):
    return 1/(1-x)-1
def sharpetest(r,sharp):
    t=1+r
    return sharp-t,t
class poslib():
    def __init__(self,tax=0.0001,reverse=False):
        self.pos={}
        self.pos["buy"]=[]
        self.pos["sell"]=[]
        self.order={}
        self.noorder=[]
        self.orderreturn=[]
        self.tax=tax
        self.checkorderprice=[]
        self.reverse=reverse
    def checkbuy(self):
        if not self.reverse:
            return self.pos["buy"]
        else:
            return self.pos["sell"]
    def checksell(self):
        if not self.reverse:
            return self.pos["sell"]
        else:
            return self.pos["buy"]
    def checkbyorder(self,p):
        if self.checkorderprice:
            if p["timekey"]==self.checkorderprice[0]["timekey"]:
                self.checkorderprice.append(p)
            else:
                for i in self.checkorderprice:
                    key=(i["timekey"],i["fx"])
                    self.updatechenck(key,p["timekey"],False,"order")
                    self.checkorderprice.remove(i)
        else:
            self.checkorderprice.append(p)
    def checkbytick(self,p):
        if self.checkorderprice:
            for i in self.checkorderprice:
                key = (i["timekey"], i["fx"])
                if i["bs"]=="B":
                    if p["LastPrice"]<i["price"]:
                        self.updatechenck(key, p["timekey"], True)
                        self.checkorderprice.remove(i)
                    else:
                        if i["timekey"].hour==15 and i["timekey"].minute==0:
                            self.updatechenck(key, p["timekey"], False)
                            self.checkorderprice.remove(i)
                else:
                    if p["LastPrice"]>i["price"]:
                        #self.checkorderprice.remove(i)
                        self.updatechenck(key, p["timekey"], True)
                        self.checkorderprice.remove(i)
                    else:
                        if i["timekey"].hour == 15 and i["timekey"].minute == 0:
                            self.updatechenck(key, p["timekey"], False)
                            self.checkorderprice.remove(i)
    def checkbybar(self,p):
        if self.checkorderprice:
            for i in self.checkorderprice:
                key = (i["timekey"], i["fx"])
                if i["bs"]=="B":
                    if p["close"]<i["price"]:
                        self.updatechenck(key, p["timekey"], True)
                        self.checkorderprice.remove(i)
                else:
                    if p["close"]>i["price"]:
                        self.updatechenck(key, p["timekey"], True)
                        self.checkorderprice.remove(i)
    def updatechenck(self,key,timekey,rst,mark="tick"):
        if key in self.order.keys():
            p=self.order[key]
            p["checkprice"]=rst
            p["checkprice_time"]=timekey
            p["mark"]=mark
        else:
            print("err updatechenck no key",key)
    def reverse_r(self):
        for i in self.orderreturn:
            t={}
            if i["type"]=="buy-sell":
                t["type"]="sell-buy"
                t["profit"] =i["openprice"]-i["closeprice"]-i["tax"]
                t["profit0"] = i["openprice"] - i["closeprice"]
                #p1["profit_byday"]
            else:
                t["type"] = "buy-sell"
                t["profit"] = i["closeprice"]-i["openprice"]-i["tax"]
                t["profit0"] = i["closeprice"] - i["openprice"]
            t["profit_byday"]=t["profit"] / i["days"]
            i.update(t)
    def openbuy(self,timekey,price):
        if self.reverse:
            self.opensell0(timekey,price)
        else:
            self.openbuy0(timekey,price)
    def opensell(self,timekey,price):
        if self.reverse:
            self.openbuy0(timekey,price)
        else:
            self.opensell0(timekey,price)
    def closebuy(self,timekey,price):
        if self.reverse:
            self.closesell0(timekey,price)
        else:
            self.closebuy0(timekey,price)
    def closesell(self,timekey,price):
        if self.reverse:
            self.closebuy0(timekey,price)
        else:
            self.closesell0(timekey,price)
    def openbuy0(self,timekey,price):
        p={}
        p["timekey"]=timekey
        p["price"]=price
        p["openclose"]="open"
        p["bs"]="B"
        p["tax"]=self.tax*price
        p["fx"]="open-buy"
        self.pos["buy"].append(p)
        key=(timekey,"open-buy")
        self.order[key]=p
        self.checkbyorder(p)
    def opensell0(self,timekey,price):
        p={}
        p["timekey"]=timekey
        p["price"]=price
        p["openclose"]="open"
        p["bs"]="S"
        p["tax"]=self.tax*price
        p["fx"] = "open-sell"
        self.pos["sell"].append(p)
        key=(timekey,"open-sell")
        self.order[key]=p
        self.checkbyorder(p)
    def closebuy0(self,timekey,price):
        p={}
        p["timekey"]=timekey
        p["price"]=price
        p["openclose"]="close"
        p["bs"]="B"
        p["tax"]=self.tax*price
        p["fx"] = "close-buy"
        key=(timekey,"close-buy")
        self.order[key]=p
        if self.pos["sell"]:
            p0 = self.pos["sell"].pop()#pop(0)
            p1={}
            p1["opentime"]=p0["timekey"]
            p1["closetime"]=p["timekey"]
            p1["openprice"]=p0["price"]
            p1["closeprice"]=p["price"]
            p1["type"]="sell-buy"
            p1["days"]=p1["closetime"]-p1["opentime"]
            if p1["days"].days==0:
                p1["days"]=1
            else:
                p1["days"]=p1["days"].days
            p1["tax"]=self.tax*price+p0["tax"]
            p1["profit0"]=p0["price"]-p["price"]
            p1["profit"]=p1["profit0"]-p1["tax"]
            p1["profit_byday"]=p1["profit"]/p1["days"]
            self.orderreturn.append(p1)
            self.checkbyorder(p)
        else:
            self.noorder.append(p)
    def forceclosebuy0(self,timekey,price):
        p={}
        p["timekey"]=timekey
        p["price"]=price
        p["openclose"]="force"
        p["bs"]="B"
        p["tax"]=self.tax*price
        p["fx"] = "close-buy"
        key=(timekey,"close-buy")
        self.order[key]=p
        #self.checkbyorder(p)
        if self.pos["sell"]:
            p0 = self.pos["sell"].pop()#pop(0)
            p1={}
            p1["opentime"]=p0["timekey"]
            p1["closetime"]=p["timekey"]
            p1["openprice"]=p0["price"]
            p1["closeprice"]=p["price"]
            p1["type"]="sell-buy"
            p1["days"]=p1["closetime"]-p1["opentime"]
            if p1["days"].days==0:
                p1["days"]=1
            else:
                p1["days"]=p1["days"].days
            p1["tax"]=self.tax*price+p0["tax"]
            p1["profit0"]=p0["price"]-p["price"]
            p1["profit"]=p1["profit0"]-p1["tax"]
            p1["profit_byday"]=p1["profit"]/p1["days"]
            self.orderreturn.append(p1)
            self.checkbyorder(p)
        else:
            self.noorder.append(p)
    def closesell0(self,timekey,price):
        p={}
        p["timekey"]=timekey
        p["price"]=price
        p["openclose"]="close"
        p["bs"]="S"
        p["tax"]=self.tax*price
        p["fx"] = "close-sell"
        key=(timekey,"close-sell")
        self.order[key]=p
        #self.checkbyorder(p)
        if self.pos["buy"]:
            p0 = self.pos["buy"].pop()#pop(0)
            p1={}
            p1["opentime"]=p0["timekey"]
            p1["closetime"]=p["timekey"]
            p1["openprice"]=p0["price"]
            p1["closeprice"]=p["price"]
            p1["type"]="buy-sell"
            p1["days"]=p1["closetime"]-p1["opentime"]
            if p1["days"].days==0:
                p1["days"]=1
            else:
                p1["days"]=p1["days"].days
            p1["tax"]=self.tax*price+p0["tax"]
            p1["profit0"]=p["price"]-p0["price"]
            p1["profit"]=p1["profit0"]-p1["tax"]
            p1["profit_byday"]=p1["profit"]/p1["days"]
            self.orderreturn.append(p1)
            self.checkbyorder(p)
        else:
            self.noorder.append(p)
    def forceclosesell0(self,timekey,price):
        p={}
        p["timekey"]=timekey
        p["price"]=price
        p["openclose"]="force"
        p["bs"]="S"
        p["tax"]=self.tax*price
        p["fx"] = "close-sell"
        key=(timekey,"close-sell")
        self.order[key]=p
        #self.checkbyorder(p)
        if self.pos["buy"]:
            p0 = self.pos["buy"].pop()#pop(0)
            p1={}
            p1["opentime"]=p0["timekey"]
            p1["closetime"]=p["timekey"]
            p1["openprice"]=p0["price"]
            p1["closeprice"]=p["price"]
            p1["type"]="buy-sell"
            p1["days"]=p1["closetime"]-p1["opentime"]
            if p1["days"].days==0:
                p1["days"]=1
            else:
                p1["days"]=p1["days"].days
            p1["tax"]=self.tax*price+p0["tax"]
            p1["profit0"]=p["price"]-p0["price"]
            p1["profit"]=p1["profit0"]-p1["tax"]
            p1["profit_byday"]=p1["profit"]/p1["days"]
            self.orderreturn.append(p1)
            self.checkbyorder(p)
        else:
            self.noorder.append(p)
    def reset(self):
        self.pos={}
    def performance_analysis(self,name="report_pos"):
        PerformanceAnalysis(self,isreport=True,a="",name="")
    def ontick(self,t):
        if t["volume"]!=0:
            self.checkbytick(t)
def copydict(a):
    b={}
    for k,v in a.items():
        b[k]=v
    return b
def PerformanceAnalysis(pos,isreport=False,a="",name=""):
    if isinstance(a,pd.DataFrame):#移仓换月处理
        ix=0
        for i in pos.orderreturn:
            ix=ix+1
            a.index=a["timekey"]
            bkey=i["opentime"]
            skey=i["closetime"]
            obj1=a.at[bkey,"obj"]
            obj2=a.at[skey,"obj"]
            if obj1!=obj2:
                ii=copydict(i)
                aix=a.loc[a["objid"]==obj1][-1:].index.values[0]
                i["closeprice"]=a.at[aix,"vwap"]
                i["closetime"]=a.at[aix,"timekey"]
                i["days"]=i["closetime"]-i["opentime"]
                i["days"]=i["days"].days
                if i["days"]==0:i["days"]=1
                i["profit0"]=i["closeprice"]-i["openprice"]
                i["profit"]=i["profit0"]-i["tax"]
                i["profit_byday"]=i["profit"]/i["days"]
                aix=a.loc[a["objid"]==obj2].index.values[0]
                ii["openprice"]=a.at[aix,"vwap"]
                ii["opentime"]=a.at[aix,"timekey"]
                ii["days"]=ii["closetime"]-ii["opentime"]
                ii["days"]=ii["days"].days
                if ii["days"]==0:ii["days"]=1
                ii["profit0"]=ii["closeprice"]-ii["openprice"]
                ii["profit"]=ii["profit0"]-ii["tax"]
                ii["profit_byday"]=ii["profit"]/ii["days"]
    rst={}
    rst["profit-total"]=0
    rst["profit-year"]=0
    rst["profit-one"]=0
    rst["总天数"]=0
    rst["总交易笔数"]=0
    rst["胜率"]=0
    rst["tax"]=0
    rst["profit-total-tax"]=0
    rst["profit-year-tax"]=0
    rst["profit-one-tax"]=0
    loss={}
    loss["总笔数"]=0
    loss["连续次数列表"]=[]
    loss["连续累计值列表"]=[]
    loss["最大连续次数"]=0
    loss["最大连续值"]=0
    loss["总值"]=0
    loss["最大值"]=0
    gain={}
    gain["总笔数"]=0
    gain["连续次数列表"]=[]
    gain["连续累计值列表"]=[]
    gain["最大连续次数"]=0
    gain["最大连续值"]=0
    gain["总值"]=0
    gain["最大值"]=0
    if pos.orderreturn:
        n=len(pos.orderreturn)
        rst["总交易笔数"]=n
        rst["总天数"]=pos.orderreturn[-1]["closetime"]-pos.orderreturn[0]["opentime"]
        rst["总天数"]=rst["总天数"].days
        if rst["总天数"]==0:
            rst["总天数"]=1
        for i in pos.orderreturn:
            rst["profit-total"]=rst["profit-total"]+i["profit0"]
            rst["profit-total-tax"]=rst["profit-total-tax"]+i["profit"]
            #rst["总交易笔数"]=rst["总交易笔数"]+1
            rst["tax"]=rst["tax"]+i["tax"]
            if i["profit"]>0:
                gain["总笔数"]=gain["总笔数"]+1
                gain["总值"]=gain["总值"]+i["profit"]
                if i["profit"]>gain["最大值"]:
                    gain["最大值"]=i["profit"]
            elif i["profit"]<0:
                loss["总笔数"]=loss["总笔数"]+1
                loss["总值"]=loss["总值"]+i["profit"]
                if i["profit"]<loss["最大值"]:
                    loss["最大值"]=i["profit"]
            if rst["总交易笔数"]!=0:
                rst["胜率"]=gain["总笔数"]/rst["总交易笔数"]
        rst0=gain2lossseq(pos.orderreturn,["profit"])
        gain["连续次数列表"]=rst0[0]["profit"]
        gain["连续累计值列表"]=rst0[2]["profit"]
        loss["连续次数列表"]=rst0[1]["profit"]
        loss["连续累计值列表"]=rst0[3]["profit"]
        gain["最大连续次数"]=max(gain["连续次数列表"])
        gain["最大连续值"]=max(gain["连续累计值列表"])
        loss["最大连续次数"]=max(loss["连续次数列表"])
        loss["最大连续值"]=min(loss["连续累计值列表"])
        rst["profit-year"]=rst["profit-total"]/(rst["总天数"]/360)
        rst["profit-one"]=rst["profit-total"]/rst["总交易笔数"]
        rst["profit-year-tax"]=rst["profit-total-tax"]/(rst["总天数"]/360)
        rst["profit-one-tax"]=rst["profit-total-tax"]/rst["总交易笔数"]
    rst["loss"]=loss
    rst["gain"]=gain
    if pos.orderreturn and isreport:
        if name=="":
            if not isinstance(a,pd.DataFrame):
                reporthtml(rst)
            else:
                kline(a,pos,rst,name="Kline")
                reporthtml(rst,"Kline")
        else:
            if not isinstance(a,pd.DataFrame):
                reporthtml(rst,name)
            else:
                kline(a,pos,rst,name)
                reporthtml(rst,name)
    return rst
def PerformanceAnalysis_no(pos,isreport=False,a="",name=""):
    rst={}
    rst["profit-total"]=0
    rst["profit-year"]=0
    rst["profit-one"]=0
    rst["总天数"]=0
    rst["总交易笔数"]=0
    rst["胜率"]=0
    rst["tax"]=0
    rst["profit-total-tax"]=0
    rst["profit-year-tax"]=0
    rst["profit-one-tax"]=0
    rst["seq_count"] = []
    rst["seq_value"] = []
    rst["checkprice_total"]=0
    rst["checkprice_order"] = 0
    rst["checkprice_price"] = 0
    rst["checkprice_loss"] = 0
    rst["checkprice_gain"] = 0
    loss={}
    loss["总笔数"]=0
    loss["连续次数列表"]=[]
    loss["连续累计值列表"]=[]
    loss["最大连续次数"]=0
    loss["最大连续值"]=0
    loss["总值"]=0
    loss["最大值"]=0
    gain={}
    gain["总笔数"]=0
    gain["连续次数列表"]=[]
    gain["连续累计值列表"]=[]
    gain["最大连续次数"]=0
    gain["最大连续值"]=0
    gain["总值"]=0
    gain["最大值"]=0
    exc={}
    exc["loss"]=[]
    exc["gain"]=[]
    exc["all"]=[]
    if pos.order:
        for k,v in pos.order.items():
            if "checkprice" in v.keys():
                if not v["checkprice"]:
                    rst["checkprice_total"]=rst["checkprice_total"]+1
                    t={}
                    t["timekey"]=v["timekey"]
                    t["price"]=v["price"]
                    t["bs"]=v["bs"]
                    t["type"]=k[1]
                    if v["mark"]=="order":
                        rst["checkprice_order"]=rst["checkprice_order"]+1
                    else:
                        rst["checkprice_price"]=rst["checkprice_price"]+1
            else:
                rst["checkprice_total"] = rst["checkprice_total"] + 1
                t = {}
                t["timekey"] = v["timekey"]
                t["price"] = v["price"]
                t["bs"] = v["bs"]
                t["type"] = k[1]
    if pos.orderreturn:
        n=len(pos.orderreturn)
        rst["总交易笔数"]=n
        rst["总天数"]=pos.orderreturn[-1]["closetime"]-pos.orderreturn[0]["opentime"]
        rst["总天数"]=rst["总天数"].days
        if rst["总天数"]==0:
            rst["总天数"]=1
        for i in pos.orderreturn:
            rst["profit-total"]=rst["profit-total"]+i["profit0"]
            rst["profit-total-tax"]=rst["profit-total-tax"]+i["profit"]
            rst["tax"]=rst["tax"]+i["tax"]
            if i["profit"]>0:
                gain["总笔数"]=gain["总笔数"]+1
                gain["总值"]=gain["总值"]+i["profit"]
                if i["profit"]>gain["最大值"]:
                    gain["最大值"]=i["profit"]
            elif i["profit"]<0:
                loss["总笔数"]=loss["总笔数"]+1
                loss["总值"]=loss["总值"]+i["profit"]
                if i["profit"]<loss["最大值"]:
                    loss["最大值"]=i["profit"]
            if rst["总交易笔数"]!=0:
                rst["胜率"]=gain["总笔数"]/rst["总交易笔数"]
        rst0=gain2lossseq(pos.orderreturn,["profit"])
        gain["连续次数列表"]=rst0[0]["profit"]
        gain["连续累计值列表"]=rst0[2]["profit"]
        loss["连续次数列表"]=rst0[1]["profit"]
        loss["连续累计值列表"]=rst0[3]["profit"]
        rst["seq_value"]=rst0[5]["profit"]
        rst["seq_count"]=rst0[4]["profit"]
        if gain["连续次数列表"]:
            gain["最大连续次数"]=max(gain["连续次数列表"])
        if gain["连续累计值列表"]:
            gain["最大连续值"]=max(gain["连续累计值列表"])
        if loss["连续次数列表"]:
            loss["最大连续次数"]=max(loss["连续次数列表"])
        if loss["连续累计值列表"]:
            loss["最大连续值"]=min(loss["连续累计值列表"])
        rst["profit-year"]=rst["profit-total"]/(rst["总天数"]/360)
        if rst["总交易笔数"]!=0:
            rst["profit-one"]=rst["profit-total"]/rst["总交易笔数"]
            rst["profit-one-tax"] = rst["profit-total-tax"] / rst["总交易笔数"]
        rst["profit-year-tax"]=rst["profit-total-tax"]/(rst["总天数"]/360)

    rst["loss"]=loss
    rst["gain"]=gain
    if pos.orderreturn and isreport:
        if name=="":
            if not isinstance(a,list):
                reporthtml(rst)
            else:
                kline(a,pos,rst,name="Kline")
                reporthtml(rst,"Kline")
        else:
            if not isinstance(a,list):
                reporthtml(rst,name)
            else:
                kline(a,pos,rst,name)
                reporthtml(rst,name)
    return rst
def reporthtml(rst,name="业绩报告"):
    loss=rst["loss"]
    gain=rst["gain"]
    from jili.report.gen_html import soup
    a={}
    a["1项目A"]=["总收益扣费","毛总收益","总费","交易次数","交易天数"]
    a["1值A"]=[rst["profit-total-tax"],rst["profit-total"],rst["tax"],rst["总交易笔数"],rst["总天数"]]
    a["2项目B"]=["年化收益扣费","日化收益扣费","毛年化收益","毛日化收益","胜率"]
    a["2值B"]=[rst["profit-year-tax"],rst["profit-one-tax"],rst["profit-year"],rst["profit-one"],rst["胜率"]]
    a["3项目C"]=["盈-总值","盈-总次","单笔最大盈","连盈最大次","连盈最大值"]
    a["3值C"]=[gain["总值"],gain["总笔数"],gain["最大值"],gain["最大连续次数"],gain["最大连续值"]]
    a["4项目D"]=["亏-总值","亏-总次","单笔最大亏","连亏最大次","连亏最大值"]
    a["4值D"]=[loss["总值"],loss["总笔数"],loss["最大值"],loss["最大连续次数"],loss["最大连续值"]]
    a["5项目E"] = ["exc-hard", "exc-hard-order", "exc-hard-price", "exc-hard-other", "aa"]
    other=rst["checkprice_total"]-rst["checkprice_order"]-rst["checkprice_price"]
    a["4值E"] = [rst["checkprice_total"], rst["checkprice_order"], rst["checkprice_price"], other, ""]
    a=pd.DataFrame(a)
    html=soup(name=name)
    html.addtitle(name)
    html.addtable(a)
    import os
    if os.path.isfile(name+".html"):
        html.addfile(name+".html",True)
    html.show(name)
    return a
    
def gain2lossseq(df,field=["profit"]):
    a={}#count
    a0={}#sum
    d={}#方向
    total_num={}
    total_val={}

    rst={}#gain count
    rst1={}#loss count
    rst2={}#gain sum
    rst3={}#loss sum
    for i in field:
        rst[i]=[]
        rst1[i]=[]
        rst2[i]=[]
        rst3[i]=[]
        total_num[i]=[]
        total_val[i]=[]
        a[i]=0
        a0[i]=0
        d[i]=0
    for i in df:
        for j in field:
            if d[j]==1:
                if i[j]>0:
                    a[j]=a[j]+1
                    a0[j]=a0[j]+i[j]
                elif i[j]<0:
                    rst2[j].append(a0[j])
                    rst[j].append(a[j])
                    total_num[j].append(a[j])
                    total_val[j].append(a0[j])
                    d[j]=-1
                    a[j]=0
                    a0[j]=0
                    a[j]=a[j]+1
                    a0[j]=a0[j]+i[j]
            elif d[j]==-1:
                if i[j]<0:
                    a[j]=a[j]+1
                    a0[j]=a0[j]+i[j]
                elif i[j]>0:
                    rst1[j].append(a[j])
                    rst3[j].append(a0[j])
                    total_num[j].append(a[j])
                    total_val[j].append(a0[j])
                    a[j]=0
                    a0[j]=0
                    d[j]=1
                    a[j]=a[j]+1
                    a0[j]=a0[j]+i[j]
            else:
                if i[j]>0:
                    d[j]=1
                    a[j]=a[j]+1
                    a0[j]=a0[j]+i[j]
                elif i[j]<0:
                    d[j]=-1
                    a[j]=a[j]+1
                    a0[j]=a0[j]+i[j]                
    return [rst,rst1,rst2,rst3,total_num,total_val]

def hist(a,name="直方分布图",legend=[],num=0,isabs=False,fx="x",issort=False,reverse=False):
    """

    :param a: [],[[],[]]
    :param name: chart name
    :param legend: "",["",""]
    :param num: 20,bar numbers;0:no number stat
    :return: bar chart
    """
    from pyecharts.charts import Page, Line, EffectScatter, Bar
    from pyecharts import options as opts
    x=[]
    y=[]
    if isinstance(a[0],list):
        if num==0:
            for aa in a:
                for i in aa:
                    if i not in x:
                        x.append(i)
            for aa in a:
                yy=[]
                for i in x:
                    if i in aa:
                        ya=0
                        for aai in aa:
                            if i==aai:
                                ya=ya+1
                        yy.append(ya)
                    else:
                        yy.append(0)
                y.append(yy)
        else:
            x0=min(a[0])
            x1=max(a[0])
            num0=len(a[0])
            num1=num0
            for aa in a:
                if x0>min(aa):
                    x0=min(aa)
                if x1<max(aa):
                    x1=max(aa)
                if num0>len(aa):
                    num0=len(aa)
                if num1<len(aa):
                    num1=len(aa)
            if num0>num:
                delta=(x1-x0)/num
                for i in range(0,num):
                    x.append(x0+i*delta)
                for aa in a:
                    yy=[]
                    for i in range(0,num):
                        y0=0
                        for j in aa:
                            if j >=x0+i*delta and j<x0+(i+1)*delta:
                                y0=y0+1
                        yy.append(y0)
                    y.append(yy)
            else:
                num=int(num0/2)
                delta=(x1-x0)/num
                for i in range(num):
                    x.append(x0+i*delta)
                for aa in a:
                    yy=[]
                    for i in range(num):
                        y0=0
                        for j in aa:
                            if j >=x0+i*delta and j<x0+(i+1)*delta:
                                y0=y0+1
                        yy.append(y0)
                    y.append(yy)
        if isabs:
            if fx=="x":
                x=abs4list(x)
            else:
                for yy in y:
                    yy=abs4list(x)
        x0=[]
        for i in x:
            x0.append(i)
        x0.sort(reverse=reverse)
        c1 = (Bar()
            .add_xaxis(x0)
            .set_global_opts(
            title_opts=opts.TitleOpts(title=name),
            toolbox_opts=opts.ToolboxOpts(),
            datazoom_opts=opts.DataZoomOpts(range_start=0, range_end=100, type_='inside', orient="both")
        )
        )
        c1.width = '1900px'
        c1.height = '900px'
        index=0
        for yy in y:
            nname=index
            if index<len(legend):
                nname=legend[index]
            if issort:
                x, yy = sort2list(x, yy,reverse=reverse)
            c1.add_yaxis(nname, yy)
            index=index+1
    else:
        if num==0:
            for i in a:
                if i not in x:
                    x.append(i)
            for i in x:
                y0 = 0
                for j in a:
                    if i == j:
                        y0 = y0 + 1
                y.append(y0)
        else:
            if len(a)>num:
                x0=min(a)
                x1=max(a)
                delta=(x1-x0)/num
                for i in range(0,num):
                    x.append(x0+i*delta)
                    y0=0
                    for j in a:
                        if j >=x0+i*delta and j<x0+(i+1)*delta:
                            y0=y0+1
                    y.append(y0)
            else:
                num=int(num/2)
                x0=min(a)
                x1=max(a)
                delta=(x1-x0)/num
                for i in range(0,num):
                    x.append(x0+i*delta)
                    y0=0
                    for j in a:
                        if j >=x0+i*delta and j<x0+(i+1)*delta:
                            y0=y0+1
                    y.append(y0)
        if issort:
            x,y=sort2list(x,y,reverse=reverse)
        c1 = (Bar()
            .add_xaxis(x)
            .set_global_opts(
            title_opts=opts.TitleOpts(title=name),
            toolbox_opts=opts.ToolboxOpts(),
            datazoom_opts=opts.DataZoomOpts(range_start=0, range_end=100, type_='inside', orient="both")
        )
        )
        c1.width = '1900px'
        c1.height = '900px'
        nname=0
        if legend:
            nname=legend
        c1.add_yaxis(nname, y)
    return c1
def sort2list(l1,l2,reverse = False):
    if l1:
        if l2:
            c = list(zip(l1, l2))
            c.sort(reverse=reverse)
            l1[:], l2[:] = zip(*c)
    return l1,l2
def abs4list(l1):
    l2=[]
    for i in l1:
        l2.append(abs(i))
    return l2
def profitkline(a,pos,ishtml=True,name="profitKline"):
    r=pos.orderreturn
    startt=r[0]["opentime"]
    a0=r[0]["openprice"]
    net=0
    rst={}
    t={}
    t["timekey"]=startt
    t["open"]=0
    t["high"]=0
    t["low"]=0
    t["close"]=0
    t["netvalue"]=0
    rst[startt]=t
    for i in r:
        if startt<i["opentime"]:
            endt=i["opentime"]
            a1=a[a["timekey"]>startt]
            a1=a1[a1["timekey"]<=endt]
            a1=a1.to_dict("index")
            for j in a1.values():
                tk=j["timekey"]
                t={}
                t["timekey"]=tk
                t["open"]=net
                t["high"]=net
                t["low"]=net
                t["close"]=net
                t["netvalue"]=net
                rst[tk]=t
            startt=i["opentime"]
            endt=i["closetime"]
            a1=a[a["timekey"]>startt]
            a1=a1[a1["timekey"]<=endt]
            a1=a1.to_dict("index")
            if i["type"]=="buy-sell":
                for j in a1.values():
                    tk=j["timekey"]
                    t={}
                    t["timekey"]=tk
                    t["open"]=net+j["open"]-i["openprice"]-i["tax"]
                    t["high"]=net+j["high"]-i["openprice"]-i["tax"]
                    t["low"]=net+j["low"]-i["openprice"]-i["tax"]
                    t["close"]=net+j["close"]-i["openprice"]-i["tax"]
                    t["netvalue"]=net+j["vwap"]-i["openprice"]-i["tax"]
                    rst[tk]=t 
            else:
                for j in a1.values():
                    tk=j["timekey"]
                    t={}
                    t["timekey"]=tk
                    t["open"]=net-j["open"]+i["openprice"]-i["tax"]
                    t["high"]=net-j["high"]+i["openprice"]-i["tax"]
                    t["low"]=net-j["low"]+i["openprice"]-i["tax"]
                    t["close"]=net-j["close"]+i["openprice"]-i["tax"]
                    t["netvalue"]=net-j["vwap"]+i["openprice"]-i["tax"]
                    rst[tk]=t
        else:
            startt=i["opentime"]
            endt=i["closetime"]
            a1=a[a["timekey"]>startt]
            a1=a1[a1["timekey"]<=endt]
            a1=a1.to_dict("index")
            if i["type"]=="buy-sell":
                for j in a1.values():
                    tk=j["timekey"]
                    t={}
                    t["timekey"]=tk
                    t["open"]=net+j["open"]-i["openprice"]-i["tax"]
                    t["high"]=net+j["high"]-i["openprice"]-i["tax"]
                    t["low"]=net+j["low"]-i["openprice"]-i["tax"]
                    t["close"]=net+j["close"]-i["openprice"]-i["tax"]
                    t["netvalue"]=net+j["vwap"]-i["openprice"]-i["tax"]
                    rst[tk]=t 
            else:
                for j in a1.values():
                    tk=j["timekey"]
                    t={}
                    t["timekey"]=tk
                    t["open"]=net-j["open"]+i["openprice"]-i["tax"]
                    t["high"]=net-j["high"]+i["openprice"]-i["tax"]
                    t["low"]=net-j["low"]+i["openprice"]-i["tax"]
                    t["close"]=net-j["close"]+i["openprice"]-i["tax"]
                    t["netvalue"]=net-j["vwap"]+i["openprice"]-i["tax"]
                    rst[tk]=t
        startt=i["closetime"]
        net=net+i["profit"]
    rst=pd.DataFrame(rst).T
    if ishtml:
        from pyecharts import Kline,online
        online()
        kline = Kline(width=1800,height=900)
        x = rst["timekey"].apply(lambda x: str(x)[:10]).tolist()
        #k_plot_value = a.apply(lambda record: [record['open'], record['close'], record['low'], record['high']], axis=1).tolist()
        kline.add(
            "Profit-KLine",
            x,
            rst.loc[:,["open", "close", "low", "high"]].values.tolist(),
            mark_point=["max","min"],
            is_datazoom_show=True,
            datazoom_type="both",
            tooltip_axispointer_type="cross",
            tooltip_trigger="axis",
            datazoom_range=[95,100],
            #datazoom_xaxis_index=[0,1]
        )
        kline.render(name+".html")
    return rst
def kline(a,pos="",rst="",name="Kline"):
    from jili.calc.chan import chan
    from pyecharts.charts import Page, Line, EffectScatter, Bar
    from pyecharts import options as opts
    c=chan()
    for i in a:
        c.onbar(i)
    kline1=c.report_kline_obj()
    page = Page(page_title=name)
    if isinstance(pos,poslib):
        buyx=[]
        buyy=[]
        sellx=[]
        selly=[]
        xx1=[]
        profits=[]
        xn=[]
        n=0
        ta=0
        for i in pos.orderreturn:
            if i["type"]=="buy-sell":
                key=str(i["opentime"])[:19]
                if key not in buyx:
                    buyx.append(key)
                    buyy.append(i["openprice"])
                key = str(i["closetime"])[:19]
                if key not in sellx:
                    sellx.append(key)
                    selly.append(i["closeprice"])
                #xn.append(n)
            else:
                key = str(i["closetime"])[:19]
                if key not in buyx:
                    buyx.append(key)
                    buyy.append(i["closeprice"])
                key = str(i["opentime"])[:19]
                if key not in sellx:
                    sellx.append(key)
                    selly.append(i["openprice"])
            xn.append(str(i["closetime"])[:19])
            n=n+1
            ta=ta+i["profit"]
            profits.append(ta)
        es1 = EffectScatter()
        es1.add_xaxis(buyx)
        es1.add_yaxis("buy", buyy,
                      symbol="arrow",
                      )
        """
        es1.set_global_opts(datazoom_opts=opts.DataZoomOpts(type_='inside',orient="both"),
                              tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="cross")
                              )
        """
        es2 = EffectScatter()
        es2.add_xaxis(sellx)
        es2.add_yaxis("sell", selly,
                      symbol="pin",
                      )
        kline1.overlap(es1)
        kline1.overlap(es2)
        line2 = Line()
        line2.add_xaxis(xn)
        line2.add_yaxis("收益曲线", profits, is_smooth=False, is_symbol_show=False,linestyle_opts=opts.LineStyleOpts(width=3))
        line2.width = '1900px'
        line2.height = '900px'
        xaxislen=100
        if len(xn)<=xaxislen:
            xaxislen=len(xn)
        xaxislen=xaxislen/len(xn)*100
        line2.set_global_opts(title_opts=opts.TitleOpts(title="收益曲线"),
                              datazoom_opts=opts.DataZoomOpts(range_start=0, range_end=xaxislen, type_='inside',orient="both"),
                              tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="cross")
                              #,markpointitem_opts=opts.MarkPointItem(type_=["max","min"])
                              )
        page.add(line2)
    if isinstance(rst,dict):
        ret=rst
        if ret["gain"]["连续次数列表"] and ret["loss"]["连续次数列表"]:
            c1 = hist([ret["gain"]["连续次数列表"], ret["loss"]["连续次数列表"]], name="gain-loss连续次数列表直方分布图", legend=["gian", "loss"],
                      num=0, isabs=False, fx="x", issort=True, reverse=False)
            page.add(c1)
            c2=hist([ret["gain"]["连续累计值列表"],ret["loss"]["连续累计值列表"]],name="gain-loss直方分布图",legend=["gian","loss"],num=100,isabs=True,fx="x",issort=True,reverse=False)
            page.add(c2)
    page.width = '1900px'
    page.height = '900px'
    page.add(kline1)
    page.render(name+".html") 
    return name+".html"
def sharptest(a,sharp=[],arg=[30,1]):
    xcmd=[]
    ycmd=[]
    if sharp:
        if isinstance(sharp,list):
            xcmd=sharp
        elif isinstance(sharp,dict):
            xcmd=sharp["x"]
            ycmd=sharp["y"]
    if not xcmd:
        for i in tag.getsharpta():
            t={}
            t["cmd"]=i
            t["name"]=[i]
            xcmd.append(t)
    if not ycmd:
        t0=dict(cmd="HLrate",arg=[5])
        t1=dict(cmd="HLrate",arg=[10])
        t2=dict(cmd="HLrate",arg=[15])
        t3=dict(cmd="HLrate",arg=[20])
        t4=dict(cmd="HLrate",arg=[40])
        ycmd.append(t0)
        ycmd.append(t1)
        ycmd.append(t2)
        ycmd.append(t3)
        ycmd.append(t4)
    a,x=tag.backward(a,xcmd)
    a,y=tag.forward(a,ycmd)
    rst={}
    for i in x:
        rst[i]={}
        b= a[a[i]!=0]
        rst[i]["count"]=b[i].dropna().count()
        for j in y:
            if j[:3]=="up5":
                rst[i]["up5"]=b[b[j]>=arg[0]][j].dropna().count()
            for ni in ["10","15","20","40"]:
                if j[:4]=="up"+ni:
                    rst[i]["up"+ni]=b[b[j]>=arg[0]][j].dropna().count()
            if j[:5]=="down5":
                rst[i]["down5"]=b[b[j]>=arg[0]][j].dropna().count()
            for ni in ["10","15","20","40"]:
                if j[:6]=="down"+ni:
                    rst[i]["down"+ni]=b[b[j]>=arg[0]][j].dropna().count()
            if j[:6]=="upvar5":
                rst[i]["upvar5"]=b[b[j]>=arg[1]][j].dropna().count()
            for ni in ["10","15","20","40"]:
                if j[:7]=="upvar"+ni:
                    rst[i]["upvar"+ni]=b[b[j]>=arg[1]][j].dropna().count()
            if j[:8]=="downvar5":
                rst[i]["downvar5"]=b[b[j]>=arg[1]][j].dropna().count()
            for ni in ["10","15","20","40"]:
                if j[:9]=="downvar"+ni:
                    rst[i]["downvar"+ni]=b[b[j]>=arg[1]][j].dropna().count()

    return rst,a,x,y
def sharpcount(a,x,y,arg=[30,1]):
    rst={}
    for i in x:
        rst[i]={}
        b= a[a[i]!=0]
        rst[i]["0-count"]=b[i].dropna().count()
        for j in y:
            if j[:3]=="up5":
                rst[i]["1-up5"]=b[(b[j]>=arg[0])&(b["upvar5_y"]>=arg[1])][j].dropna().count()
            seq=1
            for ni in ["10","15","20","40"]:
                seq=seq+1
                if j[:4]=="up"+ni:
                    rst[i][str(seq)+"-up"+ni]=b[(b[j]>=arg[0])&(b["upvar"+ni+"_y"]>=arg[1])][j].dropna().count()
            if j[:5]=="down5":
                rst[i]["1-down5"]=b[(b[j]>=arg[0])&(b["downvar5_y"]>=arg[1])][j].dropna().count()
            seq=1
            for ni in ["10","15","20","40"]:
                seq=seq+1
                if j[:6]==str(seq)+"-down"+ni:
                    rst[i]["down"+ni]=b[(b[j]>=arg[0])&(b["upvar"+ni+"_y"]>=arg[1])][j].dropna().count()
            """
            if j[:6]=="upvar5":
                rst[i]["upvar5"]=b[b[j]>=arg[1]][j].dropna().count()
            for ni in ["10","15","20","40"]:
                if j[:7]=="upvar"+ni:
                    rst[i]["upvar"+ni]=b[b[j]>=arg[1]][j].dropna().count()
            if j[:8]=="downvar5":
                rst[i]["downvar5"]=b[b[j]>=arg[1]][j].dropna().count()
            for ni in ["10","15","20","40"]:
                if j[:9]=="downvar"+ni:
                    rst[i]["downvar"+ni]=b[b[j]>=arg[1]][j].dropna().count()
            """

    return rst